/**
 * 防抖函数
 * @param {Function} func 需要防抖的函数
 * @param {number} wait 延迟时间(ms)
 * @param {boolean} immediate 是否立即执行
 * @return {Function} 返回防抖处理后的函数
 */
function debounce(func, wait = 300, immediate = false) {
  let timeout;
  
  return function(...args) {
    const context = this;
    
    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    
    const callNow = immediate && !timeout;
    
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    
    if (callNow) func.apply(context, args);
  };
}

/**
 * 节流函数
 * @param {Function} func 需要节流的函数
 * @param {number} wait 间隔时间(ms)
 * @param {Object} options 配置选项
 * @return {Function} 返回节流处理后的函数
 */
function throttle(func, wait = 300, options = {}) {
  let timeout, context, args;
  let previous = 0;
  
  const later = function() {
    previous = options.leading === false ? 0 : Date.now();
    timeout = null;
    func.apply(context, args);
    if (!timeout) context = args = null;
  };
  
  return function(...params) {
    const now = Date.now();
    if (!previous && options.leading === false) previous = now;
    
    const remaining = wait - (now - previous);
    context = this;
    args = params;
    
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
  };
}

module.exports = {
  debounce,
  throttle
}; 